<template>
  <div id="swiper">
<div class="swiper" @touchstart='touchStart' @touchmove='touchMove' @touchend='touchEnd'><slot></slot></div>
<slot name="indicator">
</slot>
<div class="indicator">
  <slot name="indicator" v-if="showIndicator && slideCount > 1">
<div v-for="(item,index) in slideCount" class="indi-item" :class='{active:index === currentIndex - 1}' :key="index"></div>
  </slot>
</div>
  </div>
</template>

<script>
export default {
 name:'Swiper',
 props:{
   //每隔三秒轮播一张图片
   interval:{
     type:Number,
     default:3000
   },
   //延迟300ms才开始轮播
   animDuration:{
     type:Number,
     default:300
   },
   //拖动比例
   moveRatio:{
     type:Number,
     default:0.25
   },
   //默认显示指示器（轮播图下面的红点）
   showIndicator:{
     type:Boolean,
     default:true
   }
 },
 data(){
   return {
     slideCount:0,//元素个数
     totalWidth:0,//swiper的宽度
     swiperStyle:{},//swiper的样式
     currentIndex:1,//当前的index
     scrolling:false//是否正在滚动
   }
 },
 mounted(){
   //1.操作DOM，在前后添加Slide
   setTimeout(()=>{
     this.handleDom();
   //2.开启定时器
     this.startTimer();
        },100)
 },
 methods:{
  //  定时器
  startTimer(){
    this.playTimer = window.setInterval(()=>{
      this.currentIndex++;
      this.scrollContent(-this.currentIndex * this.totalWidth);
    },this.interval)
  },
  stopTimer(){
    window.clearInterval(this.playTimer);
  },

  // 滚动到正确的位置
  scrollContent(currentPosition){
    // 1.设置正在滚动
    this.scrolling = true;
    // 2.开始滚动动画
    this.swiperStyle.transition = 'transform' + this.animDuration + 'ms';
    this.setTransform(currentPosition);
    //3.判断滚动到的位置
    this.checkPosition();
    //4.滚动完成
    this.scrolling=false;
  },

  //校验正确的位置
  checkPosition(){
    window.setTimeout(()=>{
      //1.校验正确位置
      this.swiperStyle.transition='0ms';
      if(this.currentIndex >= this.slideCount + 1){
        this.currentIndex = 1;
        this.setTransform(-this.currentIndex * this.totalWidth);
      }else if(this.currentIndex <= 0){
        this.currentIndex = this.slideCount;
        this.setTransform(-this.currentIndex * this.totalWidth);
      }
      //2.结束移动后的回调
      this.$emit('transitionEnd',this.currentIndex - 1);
    },this.animDuration)
  },
  
  //设置滚动的位置
  setTransform(position){
    this.swiperStyle.transform=`translated3d(${position}px,0,0)`;
    this.swiperStyle['-webkit-transform']=`translated3d(${position}px),0,0`;
    this.swiperStyle['-ms-transform']=`translated3d(${position}px),0,0`;
  },

  //操作DOM，在DOM前后添加Slide
  handleDom(){
    //1.获取要操作的元素
    let swiperEl = document.querySelector('.swiper');
    let slidesEls = swiperEl.getElementsByClassName('slide');

    //2.保存个数
    this.slideCount = slidesEls.length;

    //3.如果大于一个，那么在前后分别添加一个slide
    if(this.slideCount > 1){
      let cloneFirst = slidesEls[0].cloneNode(true);
      let cloneLast = slidesEls[this.slideCount - 1].cloneNode(true);
      swiperEl.insertBefore(cloneLast,slidesEls[0]);
      swiperEl.appendChild(cloneFirst);
      this.totalWidth = swiperEl.offsetWidth;
      this.swiperStyle = swiperEl.style;
    }
    //4.让swiper元素，显示第一个（目前是显示前面添加的最后一个元素）
    this.setTransform(-this.totalWidth);
  },

  //拖动事件处理
  touchStart(e){
    //1.如果正在滚动，不可以拖动
    if(this.scrolling)
    return;
    //2.停止定时器
    this.stopTimer();
    //3.保存开始滚动的位置
    this.startX = e.touches[0].pageX;
  },
  touchMove(e){
    //1.计算出用户拖动的距离
    this.currentX = e.touches[0].pageX;
    this.distance = this.currentX - this.startX;
    let currentPosition = -this.currentIndex * this.totalWidth;
    let moveDistance = this.distance + currentPosition;
    //2.设置当前位置
    this.setTransform(moveDistance);
  },
  touchEnd(e){
    //1.获取移动的距离
    let currentMove = Math.abs(this.distance);
    //2.判断最终的距离
    if(this.distance === 0){
      return;
    }else if(this.distance > 0 && currentMove > this.totalWidth * this.moveRatio){
      //右边移动超过0.5
      this.currentIndex--;
    }else if(this.distance < 0 && currentMove > this.totalWidth * this.moveRatio){
      //向左移动超过0.5
      this.currentIndex++;
    }
    //3.移动到正确的位置
    this.scrollContent(-this.currentIndex * this.totalWidth);
    //4.移动完成后重新开始定时器
    this.startTimer();
  },

  //控制上一个，下一个
  previous(){
    this.changeItem(-1);
  },
  next(){
    this.changeItem(1);
  },

  changeItem(num){
    //1.移除定时器
    this.startTimer();
    //2.修改index和位置
    this.currentIndex += num;
    this.scrollContent(-this.currentIndex * this.totalWidth);
    //3.添加定时器
    this.startTimer();
  }
 }
}
</script>

<style>
#swiper{
  overflow: hidden;
  position: relative;
}
.swiper{
  display:flex;
}
.indicator{
  display: flex;
  justify-content: center;
  position: absolute;
  width: 100%;
  bottom: .5rem;
}
.indi-item{
  box-sizing: border-box;
  width: .5rem;
  height: .5rem;
  border-radius: .25rem;
  background-color: #fff;
  line-height: .5rem;
  text-align: center;
  font-size: .75rem;
  margin: 0 .3125rem;
}
.indi-item .active{
  background-color: rgba(212,62,46,1.0);
}
</style>

